home *** CD-ROM | disk | FTP | other *** search
- {
- OVRSUB
- Written by Ron Schuster
- Copyright (c) 1989. All rights reserved.
- May be distributed freely, but not for a profit.
-
- See OVRSUB.DOC for complete documentation.
-
- Version 1.0, 12/28/89
- --------------------
- Initial release.
- }
-
- {$R-,S-,I-,O-,B-,F-}
- unit OvrSub;
-
- interface
- uses Overlay, Dos;
-
- function OvrSubstitute (CheckOverlayInfo, CheckEntryPts,
- CheckStaticSegs, CheckDataSeg : Boolean) : Word;
- function OvrClose : Word;
-
- implementation
-
- {$I OVRSUB.INC}
-
- function MoveFilePointer (Handle : Word; Method : Byte; Offset : LongInt) : Word;
- {-Move the file pointer of a file, given only its handle}
- {Method: 0=absolute byte offset from beginning of file
- 1=byte offset from current location
- 2=byte offset from end of file}
- var
- Regs : Registers;
- begin
- with Regs do begin
- AH := $42;
- AL := Method;
- BX := Handle;
- CX := Long(Offset).HighWord;
- DX := Long(Offset).LowWord;
- MsDos(Regs);
- if Flags and CarryFlagMask = 0 then
- MoveFilePointer := 0
- else
- MoveFilePointer := AX;
- end;
- end;
-
- function ReadFile (Handle : Word; var Buf; Count : Word; var Result : Word) : Word;
- {-Read a block from a file, given only its handle}
- var
- Regs : Registers;
- begin
- with Regs do begin
- AH := $3F;
- BX := Handle;
- CX := Count;
- DS := Seg(Buf);
- DX := Ofs(Buf);
- MsDos(Regs);
- if Flags and CarryFlagMask = 0 then begin
- ReadFile := 0;
- Result := AX;
- end
- else
- ReadFile := AX;
- end;
- end;
-
- function CloseFile (Handle : Word) : Word;
- {-Close a file, given only its handle}
- var
- Regs : Registers;
- begin
- with Regs do begin
- AH := $3E;
- BX := Handle;
- MsDos(Regs);
- if Flags and CarryFlagMask = 0 then
- CloseFile := 0
- else
- CloseFile := AX;
- end;
- end;
-
- function BlkRead(var F : word; var Buffer; Size : Word) : Boolean;
- {-Convenient shell around ReadFile}
- var
- IoResult, BytesRead : Word;
- begin
- IoResult := ReadFile(F, Buffer, Size, BytesRead);
- BlkRead := (IoResult = 0) and (BytesRead = Size);
- end;
-
- function OvrSubstitute (CheckOverlayInfo, CheckEntryPts,
- CheckStaticSegs, CheckDataSeg : Boolean) : Word;
- {-Read OVRPREP data from OVR file and adjust static dispatchers in memory}
- var
- P : Word;
- File_Ofs : LongInt;
- Static_Seg,
- Code_Size,
- Fixup_Size,
- Entry_Pts,
- TWord : Word;
- I : Integer;
- begin
- {Make sure overlay manager is initialized}
- OvrSubstitute := 1;
- if OvrDosHandle = 0 then exit;
-
- {Make sure no overlaid units are loaded}
- OvrSubstitute := 2;
- if OvrLoadList <> 0 then exit;
-
- {Read the trailer from the end of the OVR file}
- OvrSubstitute := 3;
- if MoveFilePointer (OvrDosHandle, 2, -SizeOf(Trailer)) <> 0 then exit;
- if not BlkRead (OvrDosHandle, Trailer, SizeOf(Trailer)) then exit;
-
- {Check if the signature is there}
- if Trailer.Sig <> OvrSubSignature then begin
- if CheckOverlayInfo then
- OvrSubstitute := 4
- else
- OvrSubstitute := 0;
- exit;
- end;
-
- {Move file pointer to beginning of overlay info}
- OvrSubstitute := 3;
- if MoveFilePointer (OvrDosHandle, 0, Trailer.OldFileSize) <> 0 then exit;
-
- P := System.OvrCodeList;
- while P <> 0 do begin
- if not BlkRead (OvrDosHandle, Static_Seg, SizeOf(Static_Seg)) then exit;
- if CheckStaticSegs and (P <> Static_Seg) then begin
- OvrSubstitute := 5;
- exit;
- end;
- if not BlkRead (OvrDosHandle, File_Ofs, SizeOf(File_Ofs)) then exit;
- if not BlkRead (OvrDosHandle, Code_Size, SizeOf(Code_Size)) then exit;
- if not BlkRead (OvrDosHandle, Fixup_Size, SizeOf(Fixup_Size)) then exit;
- if not BlkRead (OvrDosHandle, Entry_Pts, SizeOf(Entry_Pts)) then exit;
- with StaticDispatcher (Ptr(P+PrefixSeg+$10,0)^) do begin
- FileOfs := File_Ofs;
- CodeSize := Code_Size;
- FixupSize := Fixup_Size;
- if CheckEntryPts and (EntryPts <> Entry_Pts) then begin
- OvrSubstitute := 6;
- exit;
- end;
- for I := 1 to Entry_Pts do
- if I <= EntryPts then begin
- if not BlkRead (OvrDosHandle, Vectors[I].CodeOffset, SizeOf(Word))
- then exit;
- end
- else
- if not BlkRead (OvrDosHandle, TWord, SizeOf(TWord)) then exit;
-
- P := CodeListNext;
- end;
- end;
-
- {Get Data Segment Address and compare}
- OvrSubstitute := 7;
- if not BlkRead (OvrDosHandle, Static_Seg, SizeOf(Static_Seg)) then exit;
- if CheckDataSeg and (DSeg <> Static_Seg + PrefixSeg + $10) then exit;
-
- {Get new value for initial overlay buffer size}
- OvrSubstitute := 3;
- if not BlkRead (OvrDosHandle, OvrHeapSize, SizeOf(OvrHeapSize)) then exit;
- OvrSubstitute := 8;
- OvrSetBuf (LongInt(OvrHeapSize) shl 4);
- if OvrResult <> 0 then exit;
-
- {Make sure we're at end of file}
- OvrSubstitute := 3;
- if not BlkRead (OvrDosHandle, Trailer, SizeOf(Trailer)) then exit;
- if Trailer.Sig <> OvrSubSignature then exit;
-
- OvrSubstitute := 0;
- end;
-
- function OvrClose : Word;
- {-Clear the overlay buffer and close the current overlay file}
- begin
- OvrClearBuf;
- if CloseFile(OvrDosHandle) = 0 then begin
- OvrClose := 0;
- OvrDosHandle := 0;
- end
- else
- OvrClose := 1;
- end;
-
- end.